//
//  HMPickerView.swift
//  HealthMonitoring
//
//  Created by 珠海正杰 on 2018/9/14.
//  Copyright © 2018年 YTYanK. All rights reserved.
//

import UIKit

@objc protocol HMPickerViewDelegate: class {
    @objc func cancel()
    @objc optional func selectValue(value: String, row: Int, component: Int)
    @objc optional func selectValue(sign: String, value: String, row: Int, component: Int)
    @objc optional func didSelectValue(sign: String, value: String, rowAndComponent: Array<Any>)
    
    @objc optional func didSelectRow(pickerView: UIPickerView, row: Int, component: Int)
    @objc optional func didSelectRow(pickerView: UIPickerView, rowAndComponent: Array<Any>)
    /// 选择某个
   // @objc optional func pickerDidSelectRow(pickerView: UIPickerView, row: Int, component: Int)
}

protocol HMPickerViewDataSource: class {
//        func pickerData(_ data:Dictionary<String, AnyObject>!) -> String?
}

class HMPickerView: NSObject {
   private var _getBackgroundColor: UIColor = UIColor.white
   private var _view: UIView? // 保存创建的view
   public var sign: String = ""
   public var keyType: String = "Ary"
   public var pickerType: String = "default"
   public var isLinkage: Bool = false //默认不联动
    var getBackgroundColor: UIColor {
        get {
            return _getBackgroundColor
        }
        
        set {
            self.picker.backgroundColor = newValue
            _getBackgroundColor = newValue
        }
        
    }
    // 暂时记录
    private var temporaryAry = Array<(row: Int, com: Int)>()
//    private var linkageData = Dictionary<String,Any>()  //本意是直接传一个数组，重新拼接成一个联动的数据
    /// 是否添加view 进来  - 默认 false
    private var isTargetView: Bool = false
    var _row: Int = 0        // 单个选择
    var _component: Int = 0  // 单个选择
    var comIndex = 0 //第一个选择索引
    var oneComIndex = 0//第二个选择索引
    var twoComIndex = 0//第三个选择索引
    var isAutoSelect = false  /// 表示移动时会改变值，默认是不改变，通过按确定返回值
    var rowComAry = Array<(row: Int, com:Int)>()
//    private var componentAry = Array<Int>()
    
    public var pickerData: Dictionary<String, Any>?
    private let picker = UIPickerView()  //普通
    private let datePicker = UIDatePicker(frame: CGRect(x:0, y:0, width:320, height:216))
    private let lBtn = UIButton()
    private let rBtn = UIButton()
    private var maskView: UIView? // 遮罩
    weak var delegate: HMPickerViewDelegate?
    weak var dataSource: HMPickerViewDataSource?
    
    var rowComViewBlock: ((_ pickerView: UIPickerView, _ row: Int, _ com: Int)->())?
    var rowArrayViewBlock: ((_ pickerView: UIPickerView, _ componentAry:Array<Any>)->())?
    var rowComArrayViewBlock: ((_ pickerView: UIPickerView, _ componentAry:Array<Any>, _ com: Int)->())?
    var returnDatePicker: ((_ datePicker: UIDatePicker) -> ())?
    /// 获取自身实例
    static let sharePicker: HMPickerView = {
        let instance = HMPickerView()
        return instance
    }()
    

    class func hidePickeView() {
        let view = HMPickerView.sharePicker._view!
        let mask = HMPickerView.sharePicker.maskView
       
        UIView.animate(withDuration: 0.3, animations: {
            view.frame.origin.y = UIScreen.main.bounds.size.height
        }) { (isTrue) in
            view.removeFromSuperview()
              HMPickerView.sharePicker._view = nil
            if HMPickerView.sharePicker.isTargetView  == false {
                mask?.removeFromSuperview()
                HMPickerView.sharePicker.maskView = nil
            }
           
        }
        
 
    }
    
    /// 创建普通选择器
    //        HMPickerView.creator(nil, picker: ["AryList": [["title": yearAry[0],
    //                                                       "one-level":[
    //                                                        ["title": "xxxx1", "two-level":[["title":"two1111"],["title":"two11112"]]],
    //                                                        ["title": "xxxx222","two-level":[["title":"two2221"],["title":"two22222"],["title":"two22223"]]],
    //                                                        ["title": "xxxx333","two-level":[["title":"two3331"],["title":"two33332"],["title":"two33333"],["title":"two33334"]]],
    //                                                        ]
    //                                                       ]]
    //                                          ])

    class func creator(_ targetView: UIView?, picker data: Dictionary<String, Any>!) {
        HMPickerView.sharePicker.pickerType = "default"
        HMPickerView.sharePicker.keyType = (data! as NSDictionary).allKeys[0] as! String
        
        if targetView == nil {
                HMPickerView.sharePicker.isTargetView = false
                let app =  UIApplication.shared.delegate as! AppDelegate
                HMPickerView.sharePicker.maskView = UIView.createMaskView(this: HMPickerView.sharePicker, action: #selector(onMask(sender:)))
                app.window?.addSubview(HMPickerView.sharePicker.maskView!)
                
                HMPickerView.sharePicker.pickerData = data
                let statusH = configure.shareConfigure.statusHeight // 状态栏
                let navBarH = configure.shareConfigure.navHeight // 导航
            
                let view =  HMPickerView.sharePicker.initPicker(app.window!)
                HMPickerView.sharePicker._view = view  // view 装了 picker 的view
                
                UIView.animate(withDuration: 0.3, animations: {
                    view.frame.origin.y = UIScreen.main.bounds.size.height -  200 //( navBarH ++ statusH)
                }) { (isTrue) in
                    print("---->>", isTrue)
                }
        }else {
            HMPickerView.sharePicker.isTargetView = true
            HMPickerView.sharePicker.pickerData = data
            let statusH = configure.shareConfigure.statusHeight // 状态栏
            let navBarH = configure.shareConfigure.navHeight // 导航
            let view =  HMPickerView.sharePicker.initPicker(targetView)
            HMPickerView.sharePicker._view = view
            
            UIView.animate(withDuration: 0.3, animations: {
                view.frame.origin.y = UIScreen.main.bounds.size.height - 200 //( navBarH + 180 + statusH)
            }) { (isTrue) in
                print("---->>", isTrue)
            }
        }
//        let opts = UIViewAnimationOptions.beginFromCurrentState  HMPickerView.sharePicker.initPicker(targetView)
    }
    /// 创建日期选择器
    class func creatorDate() {
        HMPickerView.sharePicker.pickerType = "date"
        HMPickerView.sharePicker.isTargetView = false
        let app =  UIApplication.shared.delegate as! AppDelegate
        HMPickerView.sharePicker.maskView = UIView.createMaskView(this: HMPickerView.sharePicker, action: #selector(onMask(sender:)))
        app.window?.addSubview(HMPickerView.sharePicker.maskView!)
        
//        let statusH = configure.shareConfigure.statusHeight // 状态栏
//        let navBarH = configure.shareConfigure.navHeight // 导航
//
    
        let view =  HMPickerView.sharePicker.initPicker(app.window!)
        HMPickerView.sharePicker._view = view  // view 装了 picker 的view
        
        UIView.animate(withDuration: 0.3, animations: {
            view.frame.origin.y = UIScreen.main.bounds.size.height -  200 //( navBarH ++ statusH)
        }) { (isTrue) in
            print("---->>", isTrue)
        }
    }
    
    // 初始化
   private func initPicker(_ targetView: UIView!) -> UIView{

       let view = UIView()
        view.backgroundColor = _getBackgroundColor
    
        view.frame = CGRect(x: 0, y: UIScreen.main.bounds.size.height, width: UIScreen.main.bounds.size.width, height: 200)
        view.addSubview(lBtn)
        view.addSubview(rBtn)
        if pickerType == "default" {
           view.addSubview(picker)
        }else {
           view.addSubview(datePicker)
        }
        targetView.addSubview(view)
    
        lBtn.setTitle("取消", for: .normal)
        lBtn.setTitleColor(configure.shareConfigure.HMColor1, for: .normal)
        lBtn.topAlign(view: view)
        lBtn.leadingAlign(view: view)
        lBtn.widthConstrain(predicate: "100")
        lBtn.heightConstrain(predicate: "30")
        lBtn.addTarget(self, action: #selector(cancel), for: UIControlEvents.touchUpInside)
    
        rBtn.setTitle("确定", for: .normal)
//        rBtn.backgroundColor = configure.shareConfigure.HMColor1
        rBtn.isHidden = self.isAutoSelect
        rBtn.setTitleColor(configure.shareConfigure.HMColor1, for: .normal)
        rBtn.topAlign(view: view)
        rBtn.trailingAlign(view: view)
        rBtn.widthConstrain(predicate: "100")
        rBtn.heightConstrain(predicate: "30")
        rBtn.addTarget(self, action: #selector(sure), for: UIControlEvents.touchUpInside)
    
    
    if pickerType == "default" {
        // To configure picker
        picker.delegate = self
        picker.dataSource = self
        
        picker.topAlign(view: view, predicate: "50") //"38"
        picker.leadingAlign(view: view, predicate: "0")
        picker.heightConstrain(predicate: "170") //(view: view, predicate:  "150")
        picker.trailingAlign(view: view, predicate: "-0")
    }else {

        datePicker.datePickerMode = .date
        //datePicker.select  //selectRow(list.row, inComponent: list.com, animated: true)
        datePicker.locale = Locale(identifier: "zh_CN")
        datePicker.addTarget(self, action: #selector(dateChanged), for: .valueChanged)
        datePicker.topAlign(view: view, predicate: "50") //"38"
        datePicker.leadingAlign(view: view, predicate: "0")
        datePicker.heightConstrain(predicate: "170") //(view: view, predicate:  "150")
        datePicker.trailingAlign(view: view, predicate: "-0")
    }

    
    
        if self.keyType == "AryList" {
            
        if isLinkage == false {
            if self.rowComAry.count == 0 {
                self.rowComAry.removeAll()
                let aryList = self.pickerData!["AryList"] as! Array<Any>
                for i in  0..<aryList.count {
                    self.rowComAry.append((_row,i))
                    picker.selectRow(_row, inComponent: i, animated: true)
                }
            }else {
                for list in self.rowComAry {
                    
                    picker.selectRow(list.row, inComponent: list.com, animated: true)
                }
            }
        }else {
            if self.rowComAry.count == 0 {
//                self.rowComAry.removeAll()
//                let aryList = self.pickerData!["AryList"] as! Array<Any>
                
            }
        }
        
        }else  {
            picker.selectRow(_row, inComponent: _component, animated: true)
        }
   
  
    
        return view
    }
    
   // 设置时间范围n
    func setDateRange(max:Array<Int>, min:Array<Int>) {
        // 设置时间范围  NSCalendarIdentifierGregorian
        let calendar = Calendar.init(identifier: Calendar.Identifier.gregorian) //NSCalendar.init(identifier: NSCalendar.Identifier(rawValue: NSGregorianCalendar))
        let currentDate = Date.init()
        var comps = DateComponents.init()
        //设置最大时间为：当前时间推后1年
        print("====>>",max)
        comps.year = max[0]
        comps.month = max[1]
        comps.day = max[2]
        let maxDate = calendar.date(byAdding: comps, to: currentDate)  //.date(byAdding: comps, to: currentDate, options: [])
        
        //设置最小时间为：当前时间前推1年
        //        comps.year = -1
        comps.year = min[0]
        comps.month = min[1]
        comps.day = min[2]
        let minDate = calendar.date(byAdding: comps, to: currentDate)
        
        datePicker.maximumDate = maxDate
        datePicker.minimumDate = minDate
    }
   // 设置类型
    func setPickerMode(_ mode: UIDatePicker.Mode) {
        datePicker.datePickerMode = mode
    }
    
    //日期选择器响应方法
    @objc private func dateChanged(sender: UIDatePicker) {
        //更新提醒时间文本框
        let formatter = DateFormatter()
        //日期样式
        formatter.dateFormat = "yyyy年MM月dd日 HH:mm:ss"
        print(formatter.string(from: datePicker.date))
    }
    
    @objc private func cancel(sender: UIButton) {
        HMPickerView.hidePickeView()
        delegate?.cancel()
    }
    @objc private func sure(sender: UIButton) {

        var ary = Array<Any>()
//        var dic = Dictionary<String,Any>()
        var aryList = Array<Any>()
        var str = ""
        
        if pickerType == "date" { //日期选择器
             self.returnDatePicker?( self.datePicker)
        }else {  // 普通选择器部分
            if self.keyType == "Ary" {
                let row = self.picker.selectedRow(inComponent: 0)
                ary =  pickerData!["Ary"] as! Array<Any>
                str = ary[row] as! String
                _row = row
                self.rowComViewBlock?(self.picker, _row, 0)
            }else {
                aryList = pickerData!["AryList"] as! Array<Any>
                if isAutoSelect == true {
                    var i = 0
                    for item in self.rowComAry {
                        let ary = aryList[item.com] as! Array<Any>
                        
                        let rowStr = (ary[item.row] as! String) +  ( i % 2 == 0 ? "," : "")
                        str += rowStr
                        i += 1
                    }
                    
                }else {
                    let coms = self.picker.numberOfComponents // 获取总列
                    self.rowComAry.removeAll()
                    for com in 0..<coms {
                        let row = self.picker.selectedRow(inComponent: com)
                        self.rowComAry.append((row, com))
                        let ary = aryList[com] as! Array<Any>
                        let rowStr = (ary[row] as! String) +  ( com % 2 == 0 ? "," : "")
                        str += rowStr
                    }
                    self.rowArrayViewBlock?(self.picker, self.rowComAry)
                    //                self.rowComArrayViewBlock?(self.picker, self.rowComAry, )
                }
            }
            
            // 协议回调部分
            if let delegateOK = self.delegate {
                if self.keyType == "AryList" {
                    delegateOK.didSelectValue?(sign: self.sign, value: str, rowAndComponent: self.rowComAry)
                }else {
                    delegateOK.selectValue?(value: str, row: _row, component: _component)
                    delegateOK.selectValue?(sign: self.sign, value: str, row: _row, component: _component)
                }
            }
            
        }
         HMPickerView.hidePickeView()
        
    }
    
    @objc private func onMask(sender: UITapGestureRecognizer) {
       if HMPickerView.sharePicker.isTargetView  == false {
            HMPickerView.hidePickeView()
            delegate?.cancel()
        }
      
    }
}


extension HMPickerView: UIPickerViewDelegate {
    func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 44 //行高
    }
    func pickerView(_ pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        
//         let  aryList = pickerData!["AryList"] as! Array<Any>
        if self.isLinkage == false {
           return UIScreen.main.bounds.size.width/2 //列宽
        }else {
           return UIScreen.main.bounds.size.width/3 //列宽
        }
    }
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        //内容
          /*
           *  包含数组 = "Ary" ,  包含字典 = "Dic" // 暂时用 Ary
           */
//        if pickerData?.keys != nil
        
        
        if self.keyType == "Ary" {
            let ary =  pickerData!["Ary"] as! Array<Any>
            let str = ary[row] as! String
            return str
        }else {
            
            if self.isLinkage == false {
                 let aryList = pickerData!["AryList"] as! Array<Any>
                 let ary = aryList[component] as! Array<Any>
                 let str = ary[row] as! String
                 return str
            }else {
                 let aryList = pickerData!["AryList"] as! Array<Any>
                 if component == 0 {
                    let dic = aryList[row] as! Dictionary<String,Any>
                    return  dic["title"] as? String
                 }else {
                    if component == 1 {
                        let dic = aryList[comIndex] as! Dictionary<String,Any>
                        let oneLevel =  dic["one-level"]  as! Array<Any>
                        let oneRow = oneLevel[row] as! Dictionary<String,Any>
                        return oneRow["title"] as? String
                    }else {
                        let dic = aryList[comIndex] as! Dictionary<String,Any>
                        let oneLevel =  dic["one-level"]  as! Array<Any>
                        let oneRow = oneLevel[oneComIndex] as! Dictionary<String,Any>
                        let twoLevel = oneRow["two-level"] as! Array<Any>
                        let twoRow = twoLevel[row] as! Dictionary<String, Any>
                        return twoRow["title"] as? String
                    }
                 }
            
            }
        }
    }
    
    /// 移动时回调
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
           print("*------>selectRow:\(row) component \(component)")
    
        if self.keyType == "Ary" {
            if isAutoSelect == true {
              _component = component
              _row = row
            }
            
            self.delegate?.didSelectRow?(pickerView: pickerView,  row: _row, component: _component)
        }else {

            if isLinkage == false {
            
                if isAutoSelect == true {
                  self.rowComAry[component] = (row, component)
                }
               self.delegate?.didSelectRow?(pickerView: pickerView, rowAndComponent: self.rowComAry)
                
            }else {
                switch (component) {
                  case 0 :
                   self.comIndex = row
                   self.oneComIndex = 0
                   self.twoComIndex = 0
                    pickerView.reloadComponent(1)
                    pickerView.reloadComponent(2)
                    pickerView.selectRow(0, inComponent: 1, animated: false)
                    pickerView.selectRow(0, inComponent: 2, animated: false)
                  case 1:
                   self.oneComIndex = row
                   self.twoComIndex = 0
                   pickerView.reloadComponent(2)
                   pickerView.selectRow(0, inComponent: 2, animated: false)
                    
                  case 2:
                   self.twoComIndex = row
                  default:
                    break
                }
                
                
            }
        }
    }
}

extension HMPickerView: UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
       if self.keyType == "Ary" {
        return 1 //列
      }else {
        let  aryList = pickerData!["AryList"] as! Array<Any>
        if self.isLinkage == false {
          return aryList.count
        }else {
           // let aryList = pickerData!["AryList"] as! Array<Any>
           // let dic = aryList[0] as! Dictionary<String,Any>
           return 3
        }
        
      }
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
       
        if self.keyType == "Ary" {
            let ary =  pickerData!["Ary"] as! Array<Any>
            return ary.count //行
        }else {
            
            let aryList = pickerData!["AryList"] as! Array<Any>
            
            if self.isLinkage == false {
                let ary = aryList[component] as! Array<Any>
                return ary.count
            }else {
//                var comIndex = 0 //第一个选择索引
//                var oneComIndex = 0//第二个选择索引
//                var twoComIndex = 0//第三个选择索引
                
                let aryList = pickerData!["AryList"] as! Array<Any>
                
                if component == 0 {
                    return aryList.count
                }else {
                    let dic = aryList[comIndex] as! Dictionary<String,Any>
                    let oneAry = dic["one-level"] as! Array<Any>
                    if component == 1 {
                        return oneAry.count
                    }else { // if component == 2
                        let  twoLevel  = oneAry[oneComIndex] as! Dictionary<String, Any>
                        let  twoAry =  twoLevel["two-level"] as! Array<Any>
                        return twoAry.count
                    }
                }
            }
           
           
        }

    }
    
    
}
